package io.task.socket.core;

import io.task.socket.Monitor;
import io.task.socket.enums.StateMachineEnum;

import java.util.concurrent.Executor;

/**
 * 消息解码逻辑执行器
 * 异步aio-socket工作执行者
 *
 * @author MDong
 * @version 2.10.1.v20211002-RELEASE
 */
public final class DecodeWorker implements Runnable {

	private final Executor executor;

	private boolean isCanceled = false;

	private Integer result;

	private final AbstractChannelContext abstractChannelContext;

	protected DecodeWorker(AbstractChannelContext abstractChannelContext, Executor executor) {
		this.executor = executor;
		this.abstractChannelContext = abstractChannelContext;
	}

	protected void execute() {
		executor.execute(this);
	}

	@Override
	public void run() {
		if (isCanceled()) {
			return;
		}
		decode(getResult());
	}

	public boolean isCanceled() {
		return isCanceled;
	}

	public void setCanceled(boolean canceled) {
		this.isCanceled = canceled;
	}

	private Integer getResult() {
		return result;
	}

	protected DecodeWorker setResult(Integer result) {
		this.result = result;
		return this;
	}

	private Config getAioConfig() {
		return this.abstractChannelContext.getConfig();
	}

	private void decode(Integer result) {
		try {
			Monitor monitor = getAioConfig().getMonitor();
			if (monitor != null) {
				monitor.afterRead(this.abstractChannelContext, result);
			}
			this.abstractChannelContext.signalRead(result == -1);
		} catch (Exception exc) {
			getAioConfig().getHandler().stateEvent(this.abstractChannelContext, StateMachineEnum.INPUT_EXCEPTION, exc);
			this.abstractChannelContext.close(false);
		}

	}
}
